﻿using System.Linq.Expressions;
using System.Text.RegularExpressions;
using Basic.HrModel.DB;
using Basic.HrModel.Dept;
using Basic.HrModel.Emp;
using Basic.HrRemoteModel.Company.Model;
using Basic.HrRemoteModel.Dept.Model;
using Basic.HrRemoteModel.Dic.Model;
using Basic.HrRemoteModel.DicItem.Model;
using Basic.HrRemoteModel.Emp.Model;
using Basic.HrRemoteModel.EmpSignatureFile.Model;
using Basic.HrRemoteModel.LoginLog.Model;
using Basic.HrRemoteModel.Msg.Model;
using Basic.HrRemoteModel.OpLog.Model;
using Basic.HrRemoteModel.OpMenu.Model;
using Basic.HrRemoteModel.Power.Model;
using Basic.HrRemoteModel.Role.Model;
using Basic.HrRemoteModel.TreeDic.Model;
using LinqKit;
using SqlSugar;
using WeDonekRpc.Helper;
using WeDonekRpc.Helper.Validate;
using WeDonekRpc.SqlSugar;

namespace Basic.HrDAL.Repository
{
    internal static class WhereLinq
    {
        public static Expression<Func<DBEmpList, bool>> ToWhere ( this EmpFindParam param )
        {
            ExpressionStarter<DBEmpList> where = PredicateBuilder.New<DBEmpList>();
            if ( param.CompanyId.HasValue )
            {
                where = where.And(a => a.CompanyId == param.CompanyId.Value);
            }
            if ( param.LinkType == HrRemoteModel.HrLinkType.link )
            {
                where = where.And(a => a.EmpName.Contains(param.EmpName));
            }
            else if ( param.LinkType == HrRemoteModel.HrLinkType.startsWith )
            {
                where = where.And(a => a.EmpName.StartsWith(param.EmpName));
            }
            else if ( param.LinkType == HrRemoteModel.HrLinkType.endsWith )
            {
                where = where.And(a => a.EmpName.EndsWith(param.EmpName));
            }
            else
            {
                where = where.And(a => a.EmpName == param.EmpName);
            }
            return where.And(c => c.Status == HrRemoteModel.HrEmpStatus.启用);
        }
        public static Expression<Func<DBDicItem, bool>> ToWhere ( this DicItemFind param )
        {
            ExpressionStarter<DBDicItem> where = PredicateBuilder.New<DBDicItem>(a => a.DicId == param.DicId);
            if ( param.LinkType == HrRemoteModel.HrLinkType.link )
            {
                where = where.And(a => a.DicText.Contains(param.Text));
            }
            else if ( param.LinkType == HrRemoteModel.HrLinkType.startsWith )
            {
                where = where.And(a => a.DicText.StartsWith(param.Text));
            }
            else if ( param.LinkType == HrRemoteModel.HrLinkType.endsWith )
            {
                where = where.And(a => a.DicText.EndsWith(param.Text));
            }
            else
            {
                where = where.And(a => a.DicText == param.Text);
            }
            return where.And(a => a.DicStatus == HrRemoteModel.DicItemStatus.启用);
        }
        public static Expression<Func<DBTreeDicItem, bool>> ToWhere ( this TreeDicItemFind param )
        {
            ExpressionStarter<DBTreeDicItem> where = PredicateBuilder.New<DBTreeDicItem>(a => a.DicId == param.DicId);
            if ( param.LinkType == HrRemoteModel.HrLinkType.link )
            {
                where = where.And(a => a.DicText.Contains(param.Text));
            }
            else if ( param.LinkType == HrRemoteModel.HrLinkType.startsWith )
            {
                where = where.And(a => a.DicText.StartsWith(param.Text));
            }
            else if ( param.LinkType == HrRemoteModel.HrLinkType.endsWith )
            {
                where = where.And(a => a.DicText.EndsWith(param.Text));
            }
            else
            {
                where = where.And(a => a.DicText == param.Text);
            }
            return where.And(a => a.DicStatus == HrRemoteModel.DicItemStatus.启用);
        }
        public static Expression<Func<DBDept, bool>> ToWhere ( this DeptFindParam param )
        {
            ExpressionStarter<DBDept> where = PredicateBuilder.New<DBDept>();
            if ( param.CompanyId.HasValue )
            {
                where = where.And(a => a.CompanyId == param.CompanyId.Value);
            }
            if ( param.IsUnit.HasValue )
            {
                where = where.And(a => a.IsUnit == param.IsUnit.Value);
            }
            if ( param.LinkType == HrRemoteModel.HrLinkType.link )
            {
                where = where.And(a => a.DeptName.Contains(param.Name));
            }
            else if ( param.LinkType == HrRemoteModel.HrLinkType.startsWith )
            {
                where = where.And(a => a.DeptName.StartsWith(param.Name));
            }
            else if ( param.LinkType == HrRemoteModel.HrLinkType.endsWith )
            {
                where = where.And(a => a.DeptName.EndsWith(param.Name));
            }
            else
            {
                where = where.And(a => a.DeptName == param.Name);
            }
            return where;
        }
        public static Expression<Func<DBEmpMsgList, bool>> ToWhere ( this MsgGetArg query )
        {
            ///SignQueryParam
            ExpressionStarter<DBEmpMsgList> where = PredicateBuilder.New<DBEmpMsgList>(a => a.EmpId == query.EmpId && a.MsgType == query.MsgType);
            if ( !query.MsgClassify.IsNull() )
            {
                where = where.And(a => query.MsgClassify.Contains(a.MsgClassify));
            }
            if ( query.MsgStatus.HasValue )
            {
                where = where.And(a => a.MsgStatus == query.MsgStatus.Value);
            }
            if ( !query.Tag.IsNull() )
            {
                where = where.And(a => a.Tag == query.Tag);
            }
            if ( query.IsRead.HasValue )
            {
                where = where.And(a => a.IsRead == query.IsRead.Value);
            }
            return where.And(a => a.ToVoid == false);
        }
        public static Expression<Func<DBEmpSignatureFile, bool>> ToWhere ( this SignQueryParam query, long empId )
        {
            ExpressionStarter<DBEmpSignatureFile> where = PredicateBuilder.New<DBEmpSignatureFile>(a => a.EmpId == empId);
            if ( query.IsEmpUp.HasValue )
            {
                where = where.And(a => a.IsEmpUp == query.IsEmpUp.Value);
            }
            if ( query.VaildTime.HasValue )
            {
                where = where.And(a => SqlFunc.Between(query.VaildTime.Value, a.BeginTime, a.EndTime));
            }
            return where.And(a => a.IsDrop == false);
        }
        public static Expression<Func<DBEmpMsgList, bool>> ToWhere ( this MsgQuery query )
        {
            ExpressionStarter<DBEmpMsgList> where = PredicateBuilder.New<DBEmpMsgList>(a => a.EmpId == query.EmpId && a.MsgType == query.MsgType);
            if ( !query.MsgClassify.IsNull() )
            {
                where = where.And(a => query.MsgClassify.Contains(a.MsgClassify));
            }
            if ( query.AppId.HasValue )
            {
                where = where.And(a => a.AppId == query.AppId.Value);
            }
            if ( query.MsgStatus.HasValue )
            {
                where = where.And(a => a.MsgStatus == query.MsgStatus.Value);
            }
            if ( !query.Priority.IsNull() )
            {
                where = where.And(a => query.Priority.Contains(a.Priority));
            }
            if ( !query.Tag.IsNull() )
            {
                where = where.And(a => a.Tag == query.Tag);
            }
            if ( query.IsRead.HasValue )
            {
                where = where.And(a => a.IsRead == query.IsRead.Value);
            }
            if ( query.IsTimeOut.HasValue && query.IsTimeOut.Value )
            {
                where = where.And(a => a.TimeOut.HasValue && a.TimeOut < DateTime.Now);
            }
            if ( query.Begin.HasValue && query.End.HasValue )
            {
                where = where.And(a => SqlFunc.Between(a.AddTime, query.Begin.Value, query.End.Value));
            }
            else if ( query.Begin.HasValue )
            {
                where = where.And(a => a.AddTime >= query.Begin.Value);
            }
            else if ( query.End.HasValue )
            {
                where = where.And(a => a.AddTime <= query.End.Value);
            }
            if ( query.QueryKey.IsNotNull() )
            {
                where = where.And(a => a.MsgTitle.Contains(query.QueryKey));
            }
            return where.And(a => a.ToVoid == false);
        }
        public static Expression<Func<DBEmpList, bool>> ToWhere ( this EmpSearchArg query )
        {
            ExpressionStarter<DBEmpList> where = null;
            if ( !query.Title.IsNull() )
            {
                if ( !query.UnitId.IsNull() && !query.DeptId.IsNull() )
                {
                    where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.EmpId == a.EmpId && b.CompanyId == query.CompanyId && query.UnitId.Contains(b.UnitId) && query.DeptId.Contains(b.DeptId) && query.Title.Contains(b.TitleCode)).Any());
                }
                else if ( !query.DeptId.IsNull() )
                {
                    where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.EmpId == a.EmpId && b.CompanyId == query.CompanyId && query.DeptId.Contains(b.DeptId) && query.Title.Contains(b.TitleCode)).Any());
                }
                else if ( !query.UnitId.IsNull() )
                {
                    where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.EmpId == a.EmpId && b.CompanyId == query.CompanyId && query.UnitId.Contains(b.UnitId) && query.Title.Contains(b.TitleCode)).Any());
                }
                else
                {
                    where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.EmpId == a.EmpId && b.CompanyId == query.CompanyId && query.Title.Contains(b.TitleCode)).Any());
                }
            }
            else if ( !query.UnitId.IsNull() && !query.DeptId.IsNull() )
            {
                where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.EmpId == a.EmpId && b.CompanyId == query.CompanyId && query.UnitId.Contains(b.UnitId) && query.DeptId.Contains(b.DeptId)).Any());
            }
            else if ( !query.UnitId.IsNull() )
            {
                where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.EmpId == a.EmpId && b.CompanyId == query.CompanyId && query.UnitId.Contains(b.UnitId)).Any());
            }
            else if ( !query.DeptId.IsNull() )
            {
                where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.EmpId == a.EmpId && b.CompanyId == query.CompanyId && query.DeptId.Contains(b.DeptId)).Any());
            }
            else
            {
                where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.EmpId == a.EmpId && b.CompanyId == query.CompanyId).Any());
            }
            if ( !query.Post.IsNull() )
            {
                if ( !query.UnitId.IsNull() && !query.DeptId.IsNull() )
                {
                    where = where.And(a => SqlFunc.Subqueryable<DBEmpPost>().Where(b => b.CompanyId == query.CompanyId && b.EmpId == a.EmpId && query.UnitId.Contains(b.UnitId) && query.DeptId.Contains(b.DeptId) && query.Post.Contains(b.PostCode)).Any());
                }
                else if ( !query.UnitId.IsNull() )
                {
                    where = where.And(a => SqlFunc.Subqueryable<DBEmpPost>().Where(b => b.CompanyId == query.CompanyId && b.EmpId == a.EmpId && query.UnitId.Contains(b.UnitId) && query.Post.Contains(b.PostCode)).Any());
                }
                else if ( !query.DeptId.IsNull() )
                {
                    where = where.And(a => SqlFunc.Subqueryable<DBEmpPost>().Where(b => b.CompanyId == query.CompanyId && b.EmpId == a.EmpId && query.DeptId.Contains(b.DeptId) && query.Post.Contains(b.PostCode)).Any());
                }
                else
                {
                    where = where.And(a => SqlFunc.Subqueryable<DBEmpPost>().Where(b => b.CompanyId == query.CompanyId && b.EmpId == a.EmpId && query.Post.Contains(b.PostCode)).Any());
                }
            }
            return where.And(a => a.Status == HrRemoteModel.HrEmpStatus.启用 && a.IsOpenAccount);
        }
        public static Expression<Func<DBEmpList, bool>> ToWhere ( this EmpGetQuery query )
        {
            ExpressionStarter<DBEmpList> where = null;
            if ( query.IsEntry )
            {
                if ( !query.UnitId.IsNull() && !query.DeptId.IsNull() && !query.Title.IsNull() )
                {
                    where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.EmpId == a.EmpId && b.CompanyId == query.CompanyId && query.UnitId.Contains(b.UnitId) && query.DeptId.Contains(b.DeptId) && query.Title.Contains(b.TitleCode)).Any());
                }
                else if ( !query.UnitId.IsNull() && !query.DeptId.IsNull() )
                {
                    where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.EmpId == a.EmpId && b.CompanyId == query.CompanyId && query.UnitId.Contains(b.UnitId) && query.DeptId.Contains(b.DeptId)).Any());
                }
                else if ( !query.UnitId.IsNull() )
                {
                    where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.EmpId == a.EmpId && b.CompanyId == query.CompanyId && query.UnitId.Contains(b.UnitId)).Any());
                }
                else if ( !query.DeptId.IsNull() )
                {
                    where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.EmpId == a.EmpId && b.CompanyId == query.CompanyId && query.DeptId.Contains(b.DeptId)).Any());
                }
                else
                {
                    where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.EmpId == a.EmpId && b.CompanyId == query.CompanyId).Any());
                }
            }
            else
            {
                where = PredicateBuilder.New<DBEmpList>(a => a.CompanyId == query.CompanyId);
                if ( !query.UnitId.IsNull() )
                {
                    where = where.And(a => query.UnitId.Contains(a.UnitId));
                }
                if ( !query.DeptId.IsNull() )
                {
                    where = where.And(a => query.DeptId.Contains(a.DeptId));
                }
                if ( !query.Title.IsNull() )
                {
                    if ( !query.UnitId.IsNull() && !query.DeptId.IsNull() )
                    {
                        where = where.And(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.EmpId == a.EmpId && b.CompanyId == query.CompanyId && query.UnitId.Contains(b.UnitId) && query.DeptId.Contains(b.DeptId) && query.Title.Contains(b.TitleCode)).Any());
                    }
                    else if ( !query.UnitId.IsNull() )
                    {
                        where = where.And(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.EmpId == a.EmpId && b.CompanyId == query.CompanyId && query.UnitId.Contains(b.UnitId) && query.Title.Contains(b.TitleCode)).Any());
                    }
                    else if ( !query.DeptId.IsNull() )
                    {
                        where = where.And(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.EmpId == a.EmpId && b.CompanyId == query.CompanyId && query.DeptId.Contains(b.DeptId) && query.Title.Contains(b.TitleCode)).Any());
                    }
                    else
                    {
                        where = where.And(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.EmpId == a.EmpId && b.CompanyId == query.CompanyId && query.Title.Contains(b.TitleCode)).Any());
                    }
                }
            }
            if ( !query.Post.IsNull() )
            {
                if ( !query.UnitId.IsNull() && !query.DeptId.IsNull() )
                {
                    where = where.And(a => SqlFunc.Subqueryable<DBEmpPost>().Where(b => b.CompanyId == query.CompanyId && b.EmpId == a.EmpId && query.UnitId.Contains(b.UnitId) && query.DeptId.Contains(b.DeptId) && query.Post.Contains(b.PostCode)).Any());
                }
                else if ( !query.UnitId.IsNull() )
                {
                    where = where.And(a => SqlFunc.Subqueryable<DBEmpPost>().Where(b => b.CompanyId == query.CompanyId && b.EmpId == a.EmpId && query.UnitId.Contains(b.UnitId) && query.Post.Contains(b.PostCode)).Any());
                }
                else if ( !query.DeptId.IsNull() )
                {
                    where = where.And(a => SqlFunc.Subqueryable<DBEmpPost>().Where(b => b.CompanyId == query.CompanyId && b.EmpId == a.EmpId && query.DeptId.Contains(b.DeptId) && query.Post.Contains(b.PostCode)).Any());
                }
                else
                {
                    where = where.And(a => SqlFunc.Subqueryable<DBEmpPost>().Where(b => b.CompanyId == query.CompanyId && b.EmpId == a.EmpId && query.Post.Contains(b.PostCode)).Any());
                }
            }
            if ( !query.UserType.IsNull() )
            {
                where = where.And(a => query.UserType.Contains(a.UserType));
            }
            if ( query.IsOpenAccount.HasValue )
            {
                where = where.And(a => a.IsOpenAccount == query.IsOpenAccount.Value);
            }
            return where.And(a => a.Status == HrRemoteModel.HrEmpStatus.启用);
        }
        public static Expression<Func<DBOperateMenu, bool>> ToWhere ( this OpMenuQuery query )
        {
            ExpressionStarter<DBOperateMenu> where = PredicateBuilder.New<DBOperateMenu>();
            if ( query.QueryKey.IsNotNull() )
            {
                where = where.And(a => a.Title.Contains(query.QueryKey));
            }
            if ( query.BusType.IsNotNull() )
            {
                where = where.And(a => a.BusType == query.BusType);
            }
            if ( where.IsStarted )
            {
                return where;
            }
            return null;
        }
        public static Expression<Func<DBUserOperateLog, bool>> ToWhere ( this OpLogQueryParam query )
        {
            ExpressionStarter<DBUserOperateLog> where = PredicateBuilder.New<DBUserOperateLog>();
            if ( query.QueryKey.IsNotNull() )
            {
                where = where.And(a => a.Title.Contains(query.QueryKey));
            }
            if ( query.CompanyId.HasValue )
            {
                where = where.And(a => a.CompanyId == query.CompanyId.Value);
            }
            if ( query.EmpId.HasValue )
            {
                where = where.And(a => a.EmpId == query.EmpId.Value);
            }
            if ( query.IsSuccess.HasValue )
            {
                where = where.And(a => a.IsSuccess == query.IsSuccess.Value);
            }
            if ( query.BusType.IsNotNull() )
            {
                where = where.And(a => a.BusType == query.BusType);
            }
            if ( query.Begin.HasValue && query.End.HasValue )
            {
                where = where.And(a => SqlFunc.Between(a.AddTime, query.Begin.Value, query.End.Value));
            }
            else if ( query.Begin.HasValue )
            {
                where = where.And(a => a.AddTime >= query.Begin.Value);
            }
            else if ( query.End.HasValue )
            {
                where = where.And(a => a.AddTime <= query.End.Value);
            }
            if ( where.IsStarted )
            {
                return where;
            }
            return null;
        }
        public static Expression<Func<DBUserLoginLog, bool>> ToWhere ( this LoginLogQuery query )
        {
            ExpressionStarter<DBUserLoginLog> where = PredicateBuilder.New<DBUserLoginLog>();
            if ( query.QueryKey.IsNotNull() )
            {
                if ( Regex.IsMatch(query.QueryKey, @"^([.]{0,1}\d{1,3}){1,4}$", RegexOptions.IgnoreCase) )
                {
                    where = where.And(a => a.LoginIp == query.QueryKey);
                }
                else
                {
                    where = where.And(a => a.LoginName.Contains(query.QueryKey));
                }
            }
            if ( query.IsSuccess.HasValue )
            {
                where = where.And(a => a.IsSuccess == query.IsSuccess.Value);
            }
            if ( query.Begin.HasValue && query.End.HasValue )
            {
                where = where.And(a => SqlFunc.Between(a.LoginTime, query.Begin.Value, query.End.Value));
            }
            else if ( query.Begin.HasValue )
            {
                where = where.And(a => a.LoginTime >= query.Begin.Value);
            }
            else if ( query.End.HasValue )
            {
                where = where.And(a => a.LoginTime <= query.End.Value);
            }
            if ( where.IsStarted )
            {
                return where;
            }
            return null;
        }
        public static Expression<Func<DBPowerList, bool>> ToWhere ( this PowerGetParam query, long[] subSysId )
        {
            ExpressionStarter<DBPowerList> where = PredicateBuilder.New<DBPowerList>(a => subSysId.Contains(a.SubSystemId));
            if ( query.PowerType.HasValue )
            {
                where = where.And(a => a.PowerType == query.PowerType.Value);
            }
            if ( query.IsEnable.HasValue )
            {
                where = where.And(a => a.IsEnable == query.IsEnable.Value);
            }
            if ( !query.LinkType.IsNull() )
            {
                where = where.And(a => a.LinkType == query.LinkType);
            }
            return where;
        }
        public static Expression<Func<DBPowerList, bool>> ToWhere ( this PowerGetParam query, long subSysId )
        {
            ExpressionStarter<DBPowerList> where = PredicateBuilder.New<DBPowerList>(a => a.SubSystemId == subSysId);
            if ( query.PowerType.HasValue )
            {
                where = where.And(a => a.PowerType == query.PowerType.Value);
            }
            if ( query.IsEnable.HasValue )
            {
                where = where.And(a => a.IsEnable == query.IsEnable.Value);
            }
            if ( !query.LinkType.IsNull() )
            {
                where = where.And(a => a.LinkType == query.LinkType);
            }
            return where;
        }
        public static Expression<Func<DBDept, bool>> ToWhere ( this DeptQueryParam query, IRepository<DBDept> repository )
        {
            ExpressionStarter<DBDept> where = PredicateBuilder.New<DBDept>(a => a.CompanyId == query.CompanyId);
            if ( query.IsUnit.HasValue )
            {
                where = where.And(a => a.IsUnit == query.IsUnit.Value);
            }
            if ( query.UnitId.HasValue )
            {
                where = where.And(a => a.UnitId == query.UnitId.Value);
            }
            if ( !query.Status.IsNull() )
            {
                where = where.And(a => query.Status.Contains(a.Status));
            }
            if ( !query.QueryKey.IsNull() )
            {
                where = where.And(a => a.DeptName.Contains(query.QueryKey));
            }
            if ( !query.DeptId.IsNull() )
            {
                where = where.And(a => query.DeptId.Contains(a.Id));
            }
            return where.And(a => a.IsToVoid == false);
        }
        public static Expression<Func<DBDept, bool>> ToWhere ( this UnitGetParam query, IRepository<DBDept> repository )
        {
            ExpressionStarter<DBDept> where = PredicateBuilder.New<DBDept>(a => a.CompanyId == query.CompanyId);
            if ( !query.ParentId.IsNull() )
            {
                if ( query.IsAllChildren )
                {
                    if ( query.ParentId.Length == 1 )
                    {
                        string code = repository.Get(a => a.Id == query.ParentId[0], a => a.LevelCode);
                        code = code + query.ParentId[0] + "|";
                        where = where.And(a => a.LevelCode.StartsWith(code));
                    }
                    else
                    {
                        var code = repository.Gets(a => query.ParentId.Contains(a.Id), a => new
                        {
                            a.Id,
                            a.LevelCode
                        });
                        ExpressionStarter<DBDept> filter = PredicateBuilder.New<DBDept>();
                        code.ForEach(c =>
                        {
                            string t = c.LevelCode + c.Id + "|";
                            filter = filter.Or(a => a.LevelCode.StartsWith(t));
                        });
                        where = where.And(filter);
                    }
                }
                else if ( query.ParentId.Length == 1 )
                {
                    where = where.And(a => a.ParentId == query.ParentId[0]);
                }
                else
                {
                    where = where.And(a => query.ParentId.Contains(a.ParentId));
                }
            }
            if ( query.UnitId.HasValue )
            {
                where = where.And(a => a.UnitId == query.UnitId.Value);
            }
            if ( query.IsDept.GetValueOrDefault() )
            {
                where = where.And(a => a.IsUnit == false);
            }
            else if ( query.IsUnit.GetValueOrDefault() )
            {
                where = where.And(a => a.IsUnit == true);
            }
            if ( !query.Status.IsNull() )
            {
                where = where.And(a => query.Status.Contains(a.Status));
            }
            if ( !query.DeptId.IsNull() )
            {
                where = where.And(a => query.DeptId.Contains(a.Id));
            }
            return where.And(a => a.IsToVoid == false);
        }

        public static Expression<Func<DBPowerList, bool>> ToWhere ( this PowerQuery query )
        {
            ExpressionStarter<DBPowerList> where = PredicateBuilder.New<DBPowerList>(a => a.SubSystemId == query.SubSystemId);
            if ( query.ParentId.HasValue )
            {
                where = where.And(a => a.ParentId == query.ParentId.Value);
            }
            if ( query.IsEnable.HasValue )
            {
                where = where.And(a => a.IsEnable == query.IsEnable.Value);
            }
            if ( !query.PowerType.IsNull() )
            {
                where = where.And(a => query.PowerType.Contains(a.PowerType));
            }
            if ( !query.LinkType.IsNull() )
            {
                where = where.And(a => a.LinkType == query.LinkType);
            }
            if ( query.QueryKey.IsNotNull() )
            {
                where = where.And(a => a.Name.Contains(query.QueryKey));
            }
            return where;
        }
        public static Expression<Func<DBRole, bool>> ToWhere ( this RoleGetParam param )
        {
            ExpressionStarter<DBRole> where = PredicateBuilder.New<DBRole>(a => a.CompanyId == param.CompanyId);
            if ( param.IsEnable.HasValue )
            {
                where = where.And(a => a.IsEnable == param.IsEnable);
            }
            if ( param.QueryKey.IsNotNull() )
            {
                where = where.And(a => a.RoleName.Contains(param.QueryKey));
            }
            return where;
        }
        public static Expression<Func<DBDicList, bool>> ToWhere ( this DicQuery query )
        {
            ExpressionStarter<DBDicList> where = PredicateBuilder.New<DBDicList>();
            if ( !query.Status.IsNull() )
            {
                where = where.And(a => query.Status.Contains(a.Status));
            }
            if ( query.Classify.IsNotNull() )
            {
                where = where.And(a => a.DicClassify == query.Classify);
            }
            if ( query.IsSysDic.HasValue )
            {
                where = where.And(a => a.IsSysDic == query.IsSysDic.Value);
            }
            if ( query.IsTreeDic.HasValue )
            {
                where = where.And(a => a.IsTreeDic == query.IsTreeDic.Value);
            }
            if ( !query.QueryKey.IsNull() )
            {
                where = where.And(a => a.DicName.Contains(query.QueryKey));
            }
            if ( where.IsStarted )
            {
                return where;
            }
            return null;
        }
        public static Expression<Func<DBDicItem, bool>> ToWhere ( this DicItemQuery query )
        {
            ExpressionStarter<DBDicItem> where = PredicateBuilder.New<DBDicItem>(a => a.DicId == query.DicId);
            if ( !query.Status.IsNull() )
            {
                where = where.And(a => query.Status.Contains(a.DicStatus));
            }
            if ( !query.QueryKey.IsNull() )
            {
                where = where.And(a => a.DicText.Contains(query.QueryKey));
            }
            return where;
        }
        public static Expression<Func<DBTreeDicItem, bool>> ToWhere ( this TreeItemQuery query )
        {
            ExpressionStarter<DBTreeDicItem> where = PredicateBuilder.New<DBTreeDicItem>(a => a.DicId == query.DicId);
            if ( !query.Status.IsNull() )
            {
                where = where.And(a => query.Status.Contains(a.DicStatus));
            }
            if ( !query.QueryKey.IsNull() )
            {
                where = where.And(a => a.DicText.Contains(query.QueryKey));
            }
            return where;
        }
        public static Expression<Func<DBEmpList, bool>> ToWhere ( this SelectGetParam query )
        {
            ExpressionStarter<DBEmpList> where;
            if ( !query.IsEntry )
            {
                where = PredicateBuilder.New<DBEmpList>(a => a.CompanyId == query.CompanyId && a.DeptId == query.DeptId);
            }
            else
            {
                where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.CompanyId == query.CompanyId && b.DeptId == query.DeptId && b.EmpId == a.EmpId).Any());
            }
            if ( query.Post.IsNotNull() )
            {
                where = where.And(a => SqlFunc.Subqueryable<DBEmpPost>().Where(b => b.CompanyId == query.CompanyId && b.DeptId == query.DeptId && b.EmpId == a.EmpId && b.PostCode == query.Post).Any());
            }
            return where;
        }
        public static Expression<Func<DBEmpList, bool>> ToWhere ( this EmpGetParam query )
        {
            ExpressionStarter<DBEmpList> where = null;
            if ( query.IsEntry )
            {
                if ( !query.DeptId.IsNull() )
                {
                    where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.CompanyId == query.CompanyId && query.DeptId.Contains(b.DeptId) && b.EmpId == a.EmpId).Any());
                }
                else
                {
                    where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.CompanyId == query.CompanyId && b.EmpId == a.EmpId).Any());
                }
            }
            else
            {
                where = PredicateBuilder.New<DBEmpList>(a => a.CompanyId == query.CompanyId);
                if ( !query.DeptId.IsNull() )
                {
                    where = where.And(a => query.DeptId.Contains(a.DeptId));
                }
            }
            if ( !query.Status.IsNull() )
            {
                where = where.And(a => query.Status.Contains(a.Status));
            }
            return where;
        }
        public static Expression<Func<DBEmpList, bool>> ToWhere ( this EmpQuery query )
        {
            ExpressionStarter<DBEmpList> where;
            if ( query.IsLeader )
            {
                if ( !query.DeptId.IsNull() )
                {
                    where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBDept>().Where(b => b.LeaderId == a.EmpId && b.CompanyId == query.CompanyId && query.DeptId.Contains(b.Id)).Any());
                }
                else if ( !query.UnitId.IsNull() )
                {
                    where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBDept>().Where(b => b.LeaderId == a.EmpId && b.CompanyId == query.CompanyId && query.UnitId.Contains(b.Id)).Any());
                }
                else
                {
                    where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBCompany>().Where(b => b.LeaderId == a.EmpId && b.Id == query.CompanyId).Any());
                }
            }
            else if ( !query.Title.IsNull() && !query.DeptId.IsNull() )
            {
                where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.CompanyId == query.CompanyId && query.DeptId.Contains(b.DeptId) && query.Title.Contains(b.TitleCode) && b.EmpId == a.EmpId).Any());
            }
            else if ( !query.Title.IsNull() && !query.UnitId.IsNull() )
            {
                where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.CompanyId == query.CompanyId && query.UnitId.Contains(b.UnitId) && query.Title.Contains(b.TitleCode) && b.EmpId == a.EmpId).Any());
            }
            else if ( !query.Title.IsNull() )
            {
                where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.CompanyId == query.CompanyId && b.EmpId == a.EmpId && query.Title.Contains(b.TitleCode)).Any());
            }
            else if ( query.IsEntry )
            {
                if ( !query.DeptId.IsNull() )
                {
                    where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.CompanyId == query.CompanyId && query.DeptId.Contains(b.DeptId) && b.EmpId == a.EmpId).Any());
                }
                else if ( !query.UnitId.IsNull() )
                {
                    where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.CompanyId == query.CompanyId && query.UnitId.Contains(b.UnitId) && b.EmpId == a.EmpId).Any());
                }
                else
                {
                    where = PredicateBuilder.New<DBEmpList>(a => SqlFunc.Subqueryable<DBEmpTitle>().Where(b => b.CompanyId == query.CompanyId && b.EmpId == a.EmpId).Any());
                }
            }
            else
            {
                if ( !query.DeptId.IsNull() )
                {
                    where = PredicateBuilder.New<DBEmpList>(a => a.CompanyId == query.CompanyId && query.DeptId.Contains(a.DeptId));
                }
                else if ( !query.UnitId.IsNull() )
                {
                    where = PredicateBuilder.New<DBEmpList>(a => a.CompanyId == query.CompanyId && query.UnitId.Contains(a.UnitId));
                }
                else
                {
                    where = PredicateBuilder.New<DBEmpList>(a => a.CompanyId == query.CompanyId);
                }
            }
            if ( !query.Status.IsNull() )
            {
                where = where.And(a => query.Status.Contains(a.Status));
            }
            if ( !query.UserType.IsNull() )
            {
                where = where.And(a => query.UserType.Contains(a.UserType));
            }
            if ( !query.Post.IsNull() )
            {
                if ( !query.DeptId.IsNull() && !query.UnitId.IsNull() )
                {
                    where = where.And(a => SqlFunc.Subqueryable<DBEmpPost>().Where(b => b.CompanyId == query.CompanyId && b.EmpId == a.EmpId && query.UnitId.Contains(b.UnitId) && query.DeptId.Contains(b.DeptId) && query.Post.Contains(b.PostCode)).Any());
                }
                else if ( !query.DeptId.IsNull() )
                {
                    where = where.And(a => SqlFunc.Subqueryable<DBEmpPost>().Where(b => b.CompanyId == query.CompanyId && b.EmpId == a.EmpId && query.DeptId.Contains(b.DeptId) && query.Post.Contains(b.PostCode)).Any());
                }
                else if ( !query.UnitId.IsNull() )
                {
                    where = where.And(a => SqlFunc.Subqueryable<DBEmpPost>().Where(b => b.CompanyId == query.CompanyId && b.EmpId == a.EmpId && query.UnitId.Contains(b.UnitId) && query.Post.Contains(b.PostCode)).Any());
                }
                else
                {
                    where = where.And(a => SqlFunc.Subqueryable<DBEmpPost>().Where(b => b.CompanyId == query.CompanyId && b.EmpId == a.EmpId && query.Post.Contains(b.PostCode)).Any());
                }
            }
            if ( query.IsNoOpen.HasValue )
            {
                bool isOpen = query.IsNoOpen.Value == false;
                where = where.And(a => a.IsOpenAccount == isOpen);
            }
            if ( !query.RoleId.IsNull() )
            {
                where = where.And(a => SqlFunc.Subqueryable<DBEmpRole>().Where(c => c.EmpId == a.EmpId && query.RoleId.Contains(c.RoleId)).Any());
            }
            if ( !query.QueryKey.IsNull() )
            {
                if ( query.QueryKey.Validate(ValidateFormat.手机号) )
                {
                    where = where.And(a => a.Phone == query.QueryKey);
                }
                else if ( query.QueryKey.Validate(ValidateFormat.纯数字) )
                {
                    where = where.And(a => a.Phone.Contains(query.QueryKey));
                }
                else if ( query.QueryKey.Validate(ValidateFormat.数字字母) )
                {
                    where = where.And(a => a.EmpNo.Contains(query.QueryKey));
                }
                else
                {
                    where = where.And(a => a.EmpName.Contains(query.QueryKey));
                }
            }
            return where;
        }
        public static Expression<Func<DBDept, bool>> ToWhere ( this DeptGetParam query, IRepository<DBDept> repository )
        {
            ExpressionStarter<DBDept> where = LinqKit.PredicateBuilder.New<DBDept>(a => query.CompanyId.Contains(a.CompanyId));
            if ( !query.ParentId.IsNull() )
            {
                if ( query.IsAllChildren )
                {
                    if ( query.ParentId.Length == 1 )
                    {
                        long pid = query.ParentId[0];
                        string code = repository.Get(a => a.Id == query.ParentId[0], a => a.LevelCode);
                        code = code + pid + "|";
                        where = where.And(a => a.LevelCode.StartsWith(code) || a.Id == pid);
                    }
                    else
                    {
                        var code = repository.Gets(a => query.ParentId.Contains(a.Id), a => new
                        {
                            a.Id,
                            a.LevelCode
                        });
                        ExpressionStarter<DBDept> filter = PredicateBuilder.New<DBDept>(a => query.ParentId.Contains(a.Id));
                        code.ForEach(c =>
                        {
                            string t = c.LevelCode + c.Id + "|";
                            filter = filter.Or(a => a.LevelCode.StartsWith(t));
                        });
                        where = where.And(filter);
                    }
                }
                else if ( query.ParentId.Length == 1 )
                {
                    long pid = query.ParentId[0];
                    where = where.And(a => a.ParentId == pid);
                }
                else
                {
                    where = where.And(a => query.ParentId.Contains(a.ParentId) || query.ParentId.Contains(a.Id));
                }
            }
            if ( query.UnitId.HasValue )
            {
                where = where.And(a => a.UnitId == query.UnitId.Value);
            }
            if ( query.IsDept.GetValueOrDefault() )
            {
                where = where.And(a => a.IsUnit == false);
            }
            else if ( query.IsUnit.GetValueOrDefault() )
            {
                where = where.And(a => a.IsUnit == true);
            }
            if ( !query.Status.IsNull() )
            {
                where = where.And(a => query.Status.Contains(a.Status));
            }
            if ( query.DeptId.IsNull() == false )
            {
                where = where.And(a => query.DeptId.Contains(a.Id));
            }
            return where.And(a => a.IsToVoid == false);
        }
        public static Expression<Func<DBCompany, bool>> ToWhere ( this ComGetParam query, IRepository<DBCompany> repository )
        {
            ExpressionStarter<DBCompany> where = LinqKit.PredicateBuilder.New<DBCompany>();
            if ( query.ParentId.HasValue )
            {
                if ( query.IsAllChildren )
                {
                    string code = repository.Get(a => a.Id == query.ParentId.Value, a => a.LevelCode);
                    if ( code == string.Empty )
                    {
                        code = "|" + query.ParentId.Value + "|";
                    }
                    else
                    {
                        code = code + query.ParentId.Value + "|";
                    }
                    where = where.And(a => a.LevelCode.StartsWith(code));
                }
                else
                {
                    where = where.And(a => a.ParentId == query.ParentId.Value);
                }
            }
            if ( !query.Status.IsNull() )
            {
                where = where.And(a => query.Status.Contains(a.Status));
            }
            if ( !query.CompanyType.IsNull() )
            {
                where = where.And(a => query.CompanyType.Contains(a.CompanyType));
            }
            if ( where.IsStarted )
            {
                return where;
            }
            return null;
        }
    }
}
